/**
 * Created by weiwei on 11/6/18.
 */
'use strict';

// let bmap = require('../libs/baidu-map/bmap-wx.min');



//工具类


let __instance = (function () {
    let instance;
    return (newInstance) => {
        if (newInstance) instance = newInstance;
        return instance;
    }
}());

export default class Tool {

    constructor() {
        if (__instance()) return __instance();

        //init
        this.requestCount = 0;//判断加载动画是否需要隐藏

        __instance(this);
    }

    static sharedInstance() {
        return new Tool();
    }
    static formatDate = function (fmt, date) {
        date = new Date(date)

        var o = {
            "M+": date.getMonth() + 1, //月份
            "d+": date.getDate(), //日
            "h+": date.getHours(), //小时
            "m+": date.getMinutes(), //分
            "s+": date.getSeconds(), //秒
            "q+": Math.floor((date.getMonth() + 3) / 3), //季度
            "S": date.getMilliseconds() //毫秒
        };
        if (/(y+)/.test(fmt))
            fmt = fmt.replace(RegExp.$1, (date.getFullYear() + "").substr(4 - RegExp.$1.length));

        for (var k in o)
            if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
        return fmt;
    }

    static formatTime(timestamp) {
        let date = new Date(timestamp);
        let year = date.getFullYear();
        let month = date.getMonth() + 1;
        let day = date.getDate();

        let hour = date.getHours();
        let minute = date.getMinutes();
        let second = date.getSeconds();

        return [year, month, day].map(Tool.formatNumber).join('-') + ' ' + [hour, minute, second].map(Tool.formatNumber).join(':');
    }

    static formatNumber(n) {
        n = n.toString();
        return n[1] ? n : '0' + n;
    }

    static timeStringFromInterval(interval, format) {
        let date = new Date(interval * 1000);
        return this.timeStringForDate(date, format);
    }

    static stringToDate(_date, _format, _delimiter) {
        let formatLowerCase = _format.toLowerCase();
        let formatItems = formatLowerCase.split(_delimiter);
        let dateItems = _date.split(_delimiter);
        let monthIndex = formatItems.indexOf("mm");
        let dayIndex = formatItems.indexOf("dd");
        let yearIndex = formatItems.indexOf("yyyy");
        let month = parseInt(dateItems[monthIndex]);
        month -= 1;
        let formatedDate = new Date(dateItems[yearIndex], month, dateItems[dayIndex]);
        return formatedDate;
    }

    static timeIntervalFromString(string) {
        let date = Tool.dateFromString(string);
        let timeInterval = parseInt(date.getTime() / 1000);
        return timeInterval;
    }

    static timeIntervalFromNow(interval = 0) {
        return this.timeIntervalFromDate(new Date(), interval);
    }

    static timeIntervalFromDate(date, interval) {
        return parseInt(date.getTime() / 1000) + interval;
    }

    static dateFromString(string) {
        let date = new Date(string.replace(/-/g, '/'));
        return date;
    }

    static timeStringForDate(date, formate) {
        let timeString = Date.format(date, formate);
        return timeString;
    }

    static timeDurationStringForInterval(interval) {
        let str = Tool.timeStringFromInterval(interval, "YYYY MM-DD HH:mm");
        return this.timeDurationStringForDateString(str);
    }

    static timeDurationStringForDateString(string) {
        if (Tool.isEmptyStr(string)) {
            return;
        }
        let duration = parseInt(new Date().getTime() / 1000) - Tool.timeIntervalFromString(string);
        let isNegtive = duration < 0;
        if (isNegtive) {
            duration = -duration;
        }
        let time = '';
        let count = 1;
        if (duration < 60 * 60) {
            count = parseInt(duration / 60.0);
            if (count == 0) {
                time = '刚刚';
            }
            else {
                time = count + "分钟" + (isNegtive ? '后' : '前');
            }
        }
        else if (duration < (24 * 60 * 60)) {
            count = parseInt(duration / 60 / 60);
            time = count + "小时" + (isNegtive ? '后' : '前');
        } else {
            time = Tool.timeStringForDateString(string, "MM-DD HH:mm");
        }

        return (time);
    }

    static timeStringForDateString(string, formate) {
        if ('1900-01-01 00:00:00' === string) {
            // return '空';
        }
        let date = Tool.dateFromString(string);
        let timeString = Tool.timeStringForDate(date, formate);
        return timeString;
    }

    static timeStringForDate(date, formate) {
        let timeString = Date.format(date, formate);
        return timeString;
    }

    static dayCountFromInterval(interval) {
        let days = 0;
        let duration = interval - this.timeIntervalFromNow(0);
        let isNegtive = duration < 0;
        if (isNegtive) {
            duration = -duration;
        }

        days = parseInt(duration / (24 * 3600));

        return days + 1;
    }

    /**
     * 时间转为秒数 eg 8:30转为秒数
     * @param time
     * @returns {number}
     */
    static secondCountFromTime(time) {
        let arr = time.split(':');
        if (arr.length == 2) {
            let hour = arr[0]
            let min = arr[1];
            let timeInterval = hour * 60 * 60 + min * 60;
            return timeInterval;
        }
        return 0;
    }

    /**
     * 把秒数变成string
     * @param timeCount
     * @returns {string} 08:30
     */
    static timeStringForTimeCount(timeCount) {
        let hour = parseInt(timeCount / (60 * 60));
        let min = parseInt((timeCount - hour * 3600) / 60);
        let sec = parseInt(timeCount - hour * 3600 - min * 60);
        let hourString = hour + '';
        hourString = this.addZero(hourString, 2);
        let minString = min + '';
        minString = this.addZero(minString, 2);
        let secString = sec + '';
        secString = this.addZero(secString, 2);

        let openinghours = minString + ':' + secString;

        if (hourString != '00') {
            openinghours = hourString + ':' + minString + ':' + secString;
        }

        return openinghours;
    }

    // 日期倒计时

    static getDistanceTime(time, self, noDay) {
        /*replace将时间字符串中所有的'-'替换成'/',parse将时间格式的字符串转换成毫秒*/
        let endTime = new Date(Date.parse(time.replace(/-/g, "/")));
        let nowTime = new Date();
        // /*getTime把一个date对象转换成毫秒*/
        let distance = endTime.getTime() - nowTime.getTime();
        let day = 0;
        let hour = 0;
        let minute = 0;
        let second = 0;
        let distanceTime = ''
        if (distance >= 0) {
            day = Math.floor(distance / 1000 / 60 / 60 / 24);
            hour = Math.floor(distance / 1000 / 60 / 60 % 24);
            if (n) {
                hour = day * 24 + hour
            }
            minute = Math.floor(distance / 1000 / 60 % 60);
            second = Math.floor(distance / 1000 % 60);
            if (noDay) {
                distanceTime = hour + "时" + minute + "分" + second + "秒";
                if (hour == 0) {
                    distanceTime = minute + "分" + second + "秒";
                }
            } else {
                distanceTime = day + "天" + hour + "时" + minute + "分" + second + "秒";
            }
        } else {
            distanceTime = 0
        }
        self.setData({
            distanceTime: distanceTime
        })
        return distanceTime
    }

    static showDistanceTime(time) {
        let day = Math.floor(time / 60 / 60 / 24);
        let hour = Math.floor(time / 60 / 60 % 24);
        let minute = Math.floor(time / 60 % 60);
        let second = Math.floor(time % 60);
        if (time >= 0) {
            return day + "天" + hour + "时" + minute + "分" + second + "秒";
        } else {
            return 0
        }
    }

    //Object 空值判断
    static isEmpty(object) {
        if (object === null || object === undefined) {
            return true;
        }
        for (let i in object) {
            return false;
        }
        return true;
    }

    static isValid(object) {
        return !Tool.isEmpty(object);
    }

    static isEmptyObject(obj) {
        if (Tool.isEmpty(obj)) {
            return true;
        }
        for (let name in obj) {
            return false;
        }
        return true;
    }

    static isValidObject(obj) {
        return !Tool.isEmptyObject(obj);
    }

    //String 空值判断
    static isEmptyStr(str = '') {
        str = str.replace(/(^\s*)|(\s*$)/g, "")
        if (Tool.isEmpty(str)) {
            return true;
        }
        else if (str instanceof String && str.length === 0) {
            return true;
        }
        return false;
    }

    static isValidStr(str) {
        return !Tool.isEmptyStr(str);
    }

    //Array 空值判断
    static isEmptyArr(arr) {
        if (Tool.isEmpty(arr)) {
            return true;
        }
        else if (arr instanceof Array && arr.length === 0) {
            return true;
        }
        return false;
    }

    static isValidArr(arr) {
        return !Tool.isEmptyArr(arr);
    }

    /**
     * 数组是否越界判断
     */
    static isArrValidForIndex(arr, index) {
        if (Tool.isValidArr(arr) && arr.length > index) {
            return true;
        }
        return false;
    }

    static isTrue(str) {
        if (Tool.isEmptyStr(str)) {
            return false;
        }
        return 'true' === str.toLowerCase();
    }

    static isFalse(str) {
        return !Tool.isTrue(str);
    }

    static isFunction(fun) {
        return typeof fun === 'function';
    }

    //弹窗提示
    static showAlert(msg, okCB = () => {
    }, confirmText) {
        wx.showModal({
            title: '',
            content: msg,
            showCancel: false,
            confirmText: confirmText || '确认',
            success: function (res) {
                if (res.confirm) {
                    okCB();
                }
            }
        });
    }

    //弹窗自定义
    static showComfirm(msg, okCB = () => {
    }, errCB = () => {
    }, cancelText = '取消', confirmText = '确认') {
        wx.showModal({
            content: msg,
            showCancel: true,
            cancelText: cancelText,
            confirmText: confirmText,
            success: function (res) {
                if (res.confirm) {
                    okCB();
                } else {
                    errCB()
                }
            }
        });
    }

    // 成功的提示
    static showSuccessToast(title, finish = ()=> {
    }) {
        this.showToast(title, finish, 'success')
    }

    static showToast(title, finish = ()=> {
    }, icon = 'none') {
        let duration = 2000;

        let success = () => {
            if (finish) {
                setTimeout(() => {
                    finish();
                }, duration);
            }
        }

        setTimeout(() => {
            wx.showToast({
                title: title,
                icon: icon,
                duration: duration,
                success: success,
            })
        }, 400);
    }

    static pageScrollTo(scrollTop, showToast = true) {
        if (wx.pageScrollTo) {
            wx.pageScrollTo({
                scrollTop: scrollTop
            })
        } else {
            showToast && this.showToast('当前微信版本过低，无法使用该功能，请升级到最新微信版本后重试。')
        }
    }

    //显示加载动画 rCount 为请求的次数
    static showLoading(title = '加载中...') {
        if (Tool.canIUse('showLoading')) {
            wx.showLoading({title: title});
        }
        else {
            wx.showToast({
                title: title,
                icon: 'loading',
                duration: 95000
            });
        }
    }

    //隐藏加载动画
    static hideLoading() {
        if (Tool.canIUse('hideLoading')) {
            wx.hideLoading();
        }
        else {
            wx.hideToast();
        }
    }

    //返回上一个界面
    static navigationPop() {
        wx.navigateBack({
            delta: 1
        });
    }

    /**
     * 从数组中移除一个对象
     * @param obj
     * @param arr
     * @returns {*}
     */
    static removeObjectFromArray(obj, arr) {
        let index = arr.indexOf(obj);
        if (index > -1) {
            arr.splice(index, 1);
        }

        return arr;
    }

    /**
     * str是否已needle开头
     *
     * @param str
     * @param needle
     * @returns {boolean}
     */
    static isStringStartsWith(str, needle) {
        return str.lastIndexOf(needle, 0) === 0
    }

	static addZero(str, length) {
		return new Array(length - str.length + 1).join("0") + str;
	}

	static addZeroCommon(num) {
    	return typeof num === 'number' ? (num > 9 ? num : '0' + num) : num
	}

    static redirectTo(url, success, fail, complete) {
        wx.redirectTo({
                url: url,
                success: success,
                fail: fail,
                complete: complete,
            }
        )
    }

    static switchTab(url, success, fail, complete) {
        wx.switchTab({
            url: url,
            success: success,
            fail: fail,
            complete: complete,
        })
    }

    static navigateTo(url, success, fail, complete) {
        wx.navigateTo({
            url: url,
            success: success,
            fail: fail,
            complete: complete,
        })
    }

    /**
     * 查看权限
     * @param scope
     * @param success
     * @param fail
     */
    static getScope(scope, success, fail, complete, notCompatible) {
        if (wx.canIUse('getSetting') && wx.canIUse('authorize')) {
            wx.getSetting({
                success(res) {
                    if (!res[scope]) {
                        wx.authorize({
                            scope: scope,
                            success() {
                                console.log(scope + ' success');
                                if (this.isFunction(success)) {
                                    success();
                                }
                            },
                            fail() {
                                console.log(scope + ' fail');
                                if (this.isFunction(fail)) {
                                    fail();
                                }
                            },
                            complete() {
                                console.log(scope + ' complete');
                                if (this.isFunction(complete)) {
                                    complete();
                                }
                            },
                        })
                    }
                },
                fail(res) {
                    console.log('authorize、getSetting 不兼容当前版本');
                    if (this.isFunction(notCompatible)) {
                        notCompatible();
                    }
                }
            })
        }
        else {
            console.log('authorize、getSetting 不兼容当前版本');
            if (this.isFunction(notCompatible)) {
                notCompatible();
            }
        }
    }

    static canIUse(method) {
        let canIUse = wx.canIUse(method);
        if (canIUse === false) {
            console.log('方法：' + method + '不兼容当前版本，无法使用');
        }
        return canIUse;
    }

    /**
     * 获取地理位置，自动处理授权提示
     * @param success
     * @param fail
     * @param complete
     */
    static getLocation(success = (res) => {
    }, fail = () => {
    }, complete = () => {
    }) {
        let resultHandler = (success, fail, complete) => {
            Tool.queryLocation((res) => {
                if (Tool.isValid(res)) {
                    success(res);
                }
                else {
                    fail();
                }
            }, () => {
                complete();
            });
        }

        //请求授权获取地理位置信息
        this.getScope('scope.userLocation',
            //成功
            () => {
                resultHandler(success, fail, complete);
            },
            //失败
            () => {
                fail();
            },
            //完成
            () => {
                complete();
            },
            //不兼容，直接请求地址
            () => {
                resultHandler(success, fail, complete);
            });
    }

    //调用微信接口，获取定位信息
    static queryLocation(cb = (res) => {
    }, complete = () => {
    }) {
        wx.getLocation({
            // type:'gcj02',
            success: function (res) {
                let that = this;
                /* 获取定位地理位置 */
                // 新建bmap对象
                // let BMap = new bmap.BMapWX({
                //     ak: config.BaiduMapKey
                // });
                // let fail = function (data) {
                //     console.log(data);
                // };
                // let success = function (data) {
                //     //返回数据内，已经包含经纬度
                //     res.wxMarkerData = data.wxMarkerData;
                //     res.originalData = data.originalData;
                //     cb(res);
                // }
                // // 发起regeocoding检索请求
                // BMap.regeocoding({
                //     fail: fail,
                //     success: success
                // });
            },
            fail: function () {
                cb(null);
            },
            complete: function () {
                complete();
            }
        })
    }

    static chooseImg(imgCount = 1, succCb = ()=> {
    }, errCb = ()=> {
    }) {
        let that = this
        wx.chooseImage({
            count: imgCount, // 默认9
            sizeType: ['compressed'], // 可以指定是原图还是压缩图，默认二者都有
            sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机，默认二者都有
            success(res) {
                // 返回选定照片的本地文件路径列表，tempFilePath可以作为img标签的src属性显示图片
                let tempFilePaths = res.tempFilePaths;
                if (tempFilePaths[0].lastIndexOf('.gif') != -1) {
                    that.showToast('不支持gif格式图片')
                    return
                }
                let tempFilesSize = res.tempFiles[0].size

                if (tempFilesSize <= 3145728) {
                    that.showLoading()
                    succCb(tempFilePaths)
                } else {
                    that.hideLoading()
                    that.showToast('上传图片不能大于3M')
                }
            },
            fail(res) {
                errCb()
            }
        })
    }

    /**
     * 判断密码
     */
    static checkPwd(value) {
        let Regx = /^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{6,18}$/;
        if (Regx.test(value)) {
            return true;
        }
        else {
            return false;
        }
    }

    // 判断手机号
    static checkPhone(value) {
        value = value.replace(/(^\s*)|(\s*$)/g, "")
        let reg = /^[1][3,4,5,6,7,8,9][0-9]{9}$/
        if (reg.test(value)) {
            return true;
        } else {
            return false;
        }
    }

    // 判断人名
    static checkName(value) {
        ///^([a-zA-Z0-9\u4e00-\u9fa5\·]{2,16})$/
        if (!(/^[\u4E00-\u9FA5\uf900-\ufa2d·s]{2,16}$/.test(value))) {
            return false
        } else {
            return true
        }
    }

    // 判断身份证号是否适合规格
    static checkIdentityCode(num) {
        num = num.toUpperCase();
        //身份证号码为15位或者18位，15位时全为数字，18位前17位为数字，最后一位是校验位，可能为数字或字符X。
        if (!(/(^\d{15}$)|(^\d{17}([0-9]|X)$)/.test(num))) {
            // alert('输入的身份证号长度不对，或者号码不符合规定！\n15位号码应全为数字，18位号码末位可以为数字或X。');
            return false
        }
        //校验位按照ISO 7064:1983.MOD 11-2的规定生成，X可以认为是数字10。
        //下面分别分析出生日期和校验位
        var len, re;
        len = num.length;
        if (len == 15) {
            re = new RegExp(/^(\d{6})(\d{2})(\d{2})(\d{2})(\d{3})$/);
            var arrSplit = num.match(re);
            //检查生日日期是否正确
            var dtmBirth = new Date('19' + arrSplit[2] + '/' + arrSplit[3] + '/' + arrSplit[4]);
            var bGoodDay;
            bGoodDay = (dtmBirth.getYear() == Number(arrSplit[2]))
                && ((dtmBirth.getMonth() + 1) == Number(arrSplit[3]))
                && (dtmBirth.getDate() == Number(arrSplit[4]))
            if (!bGoodDay) {
                // alert('输入的身份证号里出生日期不对！')
                return false
            } else {
                //将15位身份证转成18位
                //校验位按照ISO 7064:1983.MOD 11-2的规定生成，X可以认为是数字10。
                var arrInt = new Array(7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2);
                var arrCh = new Array('1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2');
                var nTemp = 0, i;
                num = num.substr(0, 6) + '19' + num.substr(6, num.length - 6);
                for (i = 0; i < 17; i++) {
                    nTemp += num.substr(i, 1) * arrInt[i];
                }
                num += arrCh[nTemp % 11];
                return num
            }
        }
        if (len == 18) {
            re = new RegExp(/^(\d{6})(\d{4})(\d{2})(\d{2})(\d{3})([0-9]|X)$/);
            var arrSplit = num.match(re)
            //检查生日日期是否正确
            var dtmBirth = new Date(arrSplit[2] + "/" + arrSplit[3] + "/" + arrSplit[4]);
            var bGoodDay;
            bGoodDay = (dtmBirth.getFullYear() == Number(arrSplit[2]))
                && ((dtmBirth.getMonth() + 1) == Number(arrSplit[3]))
                && (dtmBirth.getDate() == Number(arrSplit[4]));
            if (!bGoodDay) {
                // alert(dtmBirth.getYear());
                //alert(arrSplit[2]);
                //alert('输入的身份证号里出生日期不对！');
                return false
            } else {
                //检验18位身份证的校验码是否正确。
                //校验位按照ISO 7064:1983.MOD 11-2的规定生成，X可以认为是数字10。
                var valnum;
                var arrInt = new Array(7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2);
                var arrCh = new Array('1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2');
                var nTemp = 0, i;
                for (i = 0; i < 17; i++) {
                    nTemp += num.substr(i, 1) * arrInt[i]
                }
                valnum = arrCh[nTemp % 11];
                if (valnum != num.substr(17, 1)) {
                    //alert('18位身份证的校验码不正确！应该为：' + valnum);
                    return false
                }
                return num
            }
        }
        return false
    }

    // 获取用户账号信息

    static getUserInfos(that) {
        let userInfo = global.$util.Storage.getUserAccountInfo()
        if (userInfo) {
            let idcard = userInfo.idcard
            userInfo.showName = idcard ? userInfo.realname : userInfo.nickname
            userInfo.isRealname = idcard ? true : false
            // userInfo.showPhone = userInfo.phone.slice(0, 3) + "*****" + userInfo.phone.slice(7)
            userInfo.showPhone = userInfo.phone
            if (userInfo.province) userInfo.showRegion = userInfo.province + userInfo.city + userInfo.area
            if (!userInfo.area) userInfo.showRegion = userInfo.province + userInfo.city
        }
        if(that){
            that.setData({
                userInfos: userInfo || {}
            })
        }
        return userInfo
    }

    // 倒计时是否可以点击

    static codeEnable(that, cb = ()=> {
    }) {
        let tempEnable = that.data.getCodeBtEnable
        if (!tempEnable) {
            return
        }
        that.data.getCodeBtEnable = !tempEnable
        that.setData({
            showSecond: true
        })
        this.countdown(that, this);
        cb()
    }

    // 倒计时

    static countdown(that, self) {
        // that 调用页面中的this slef 当前页面调用的this
        let second = that.data.second
        clearTimeout(that.data.time)
        if (second == 0) {
            that.data.getCodeBtEnable = true
            that.setData({
                second: '59',
                showSecond: false
            });
            return;
        }
        let time = setTimeout(function () {
            that.data.getCodeBtEnable = false
            that.setData({
                second: second - 1,
                showSecond: true,
            })
            self.countdown(that, self)
        }, 1000)
        that.data.time = time
    }


    // 格式化服务器端返回的cookie

    static formatCookie(cookies) {
        let __cookies = [];
        (cookies.match(/([\w\-.]*)=([^\s]+);/g) || []).forEach((str) => {
            if (str.indexOf('Path=/') !== 0) {
                __cookies.push(str);
            } else if (str.indexOf('token2') != -1) {
                let token2 = str.slice(7)
                __cookies.push(token2);
            }
        });
        //  最后发送的
        let myCookie = __cookies.join('')
        global.$util.Storage.setUserCookie(myCookie)
        return myCookie
    }

    // 是否登录

    static didLogin(that) {
        let userInfo = global.$util.Storage.getUserAccountInfo() ? global.$util.Storage.getUserAccountInfo() : {}
        let didLogin = userInfo.code && global.$util.Storage.getToken() ? true : false
        if(that){
            that.setData({
                didLogin: didLogin
            })
        }
        return didLogin
    }

    // 登录以后的操作

    static loginOpt(req) {
        let datas = req.data || {}
        const {Storage, Event} = global.$util
        if (datas.token) {
            Storage.setToken(datas.token)
        }
        Storage.setUserAccountInfo(datas)
        Event.emit('didLogin');
        Storage.setWxOpenid(datas.openid)
        datas.unionid && Storage.setWxUnionid(datas.unionid)
        Storage.setMemberId(datas.code)
        Event.emit('refreshMemberInfoNotice')
    }

    /*获取当前页url*/
    static getCurrentPageUrl() {
        let pages = getCurrentPages()    //获取加载的页面
        let currentPage = pages[pages.length - 1]    //获取当前页面的对象
        let url = currentPage.route    //当前页面url
        return url
    }

    /*获取当前页带参数的url*/
    static getCurrentPageUrlWithArgs() {
        let pages = getCurrentPages()    //获取加载的页面
        let currentPage = pages[pages.length - 1]    //获取当前页面的对象
        let url = currentPage.route    //当前页面url
        let options = currentPage.options    //如果要获取url中所带的参数可以查看options

        //拼接url的参数
        let urlWithArgs = url + '?'
        for (let key in options) {
            let value = options[key]
            urlWithArgs += key + '=' + value + '&'
        }
        urlWithArgs = urlWithArgs.substring(0, urlWithArgs.length - 1)

        return urlWithArgs
    }

    // 阻止多次跳转
    static throttle(fn, gapTime) {
        if (gapTime == null || gapTime == undefined) {
            gapTime = 1500
        }

        let _lastTime = null

        // 返回新的函数
        return function () {
            let _nowTime = +new Date()
            if (_nowTime - _lastTime > gapTime || !_lastTime) {
                fn.apply(this, arguments)   //将this和参数传给原函数
                _lastTime = _nowTime
            }
        }
    }

    // 防止前端精度缺失

    // 加
    static add(arg1 = 0, arg2 = 0) {
        let r1, r2, m, c;
        try {
            r1 = arg1.toString().split(".")[1].length;
        }
        catch (e) {
            r1 = 0;
        }
        try {
            r2 = arg2.toString().split(".")[1].length;
        }
        catch (e) {
            r2 = 0;
        }
        c = Math.abs(r1 - r2);
        m = Math.pow(10, Math.max(r1, r2));
        if (c > 0) {
            let cm = Math.pow(10, c);
            if (r1 > r2) {
                arg1 = Number(arg1.toString().replace(".", ""));
                arg2 = Number(arg2.toString().replace(".", "")) * cm;
            } else {
                arg1 = Number(arg1.toString().replace(".", "")) * cm;
                arg2 = Number(arg2.toString().replace(".", ""));
            }
        } else {
            arg1 = Number(arg1.toString().replace(".", ""));
            arg2 = Number(arg2.toString().replace(".", ""));
        }
        return (arg1 + arg2) / m;
    }

    // 减
    static sub(arg1 = 0, arg2 = 0) {
        let r1, r2, m, n;
        try {
            r1 = arg1.toString().split(".")[1].length;
        }
        catch (e) {
            r1 = 0;
        }
        try {
            r2 = arg2.toString().split(".")[1].length;
        }
        catch (e) {
            r2 = 0;
        }
        m = Math.pow(10, Math.max(r1, r2));
        n = (r1 >= r2) ? r1 : r2;
        return Number(((arg1 * m - arg2 * m) / m).toFixed(n));

    }

    // 乘法
    static mul(arg1 = 0, arg2 = 0) {
        let m = 0, s1 = arg1.toString(), s2 = arg2.toString();
        try {
            m += s1.split(".")[1].length;
        }
        catch (e) {
        }
        try {
            m += s2.split(".")[1].length;
        }
        catch (e) {
        }
        return Number(s1.replace(".", "")) * Number(s2.replace(".", "")) / Math.pow(10, m);
    }

    // 是否是iPhone 34rpx的底部像素差

    static isIPhoneX(that) {
        let isIPhoneX = global.$util.Storage.sysInfo().isIphoneX
        let className = isIPhoneX ? 'fixed-bottom-iPhoneX' : 'fixed-bottom'
        let showBottom = isIPhoneX
        that.setData({
            isIPhoneX: {isIPhoneX, showBottom, className}
        })
        return {isIPhoneX, showBottom, className}
    }

    static isIphoneXR_XS() {
        const sysInfo = global.$util.Storage.sysInfo();
        let flag = false;
        ['iPhone11,8', 'iPhone11,2', 'iPhone11,4', 'iPhone11,6', 'iPhone XS', 'iPhone XR', 'iPhone XS Max'].forEach((item) => {
            if (sysInfo.model.search(item) != -1) flag = true;
        })
        return flag;
    }

    // 根据屏幕大小 高度自适应

    static getAdaptHeight(e, that) {
        //获取图片真实宽度
        let imgwidth = e.detail.width,
            imgheight = e.detail.height,
            //宽高比
            ratio = imgwidth / imgheight;
        //计算的高度值
        let viewHeight = 750 / ratio;
        imgheight = viewHeight
        let imgheights = that.data.imgheights || []
        //把每一张图片的高度记录到数组里
        imgheights.push(imgheight)
        that.setData({
            imgheights: imgheights,
        })
    }

    static formatNum(num) { // 保留两位小数不四舍五入
        num = Number(num)
        num = num < 0 ? 0 : num
        let index = String(num).lastIndexOf('.')
        if (index != -1) {
            let num2 = num.toFixed(3);
            num2 = num2.substring(0, num2.lastIndexOf('.') + 3)
            return num2
        } else {
            num = num + '.00'
        }
        return num
    }

    // 冒泡排序
    static bubbleSort(array) {
        let i = 0, len = array.length, j, d;
        for (; i < len; i++) {
            for (j = 0; j < len; j++) {
                if (array[i] < array[j]) {
                    d = array[j];
                    array[j] = array[i];
                    array[i] = d;
                }
            }
        }
        return array;
    }

    // 平均分割数字
    static sliceArray(array, num) {
        let result = [];
        for (let i = 0, len = array.length; i < len; i += num) {
            result.push(array.slice(i, i + num));
        }
        return result
    }

    static getUUID() {
        return 'xxxx-xxxx-xxxx-xxxx-xxxx'.replace(/[xy]/g, function (c) {
            let r = Math.random() * 16 | 0, v = c === 'x' ? r : (r & 0x3 | 0x8);
            return v.toString(16);
        });
    }

    // 去掉输入的表情符号
    static formatString(str) {
        return str.replace(/\uD83C[\uDF00-\uDFFF]|\uD83D[\uDC00-\uDE4F]/g, "")
    }

    // 位运算

    static bitOperation(arr, num) {
        let result = arr.filter((item0) => {
            let bit = item0 & num
            return bit == item0
        })
        return result
    }

    // 判断是不是json
    static isJson(text) {
        if (/^[\],:{}\s]*$/.test(text.replace(/\\["\\\/bfnrtu]/g, '@').replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']').replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
            return true

        } else {

            return false

        }
    }

    // 配合rich-text 对字符串里的转译文案进行转换   后期待扩充
    static htmlEscape(html) {
        if (!html) {
            return ""
        }
        var reg = /(&lt;)|(&gt;)|(&amp;)|(&quot;)|(\n)/g;
        return html.replace(reg, function (match) {
            switch (match) {
                case "&lt;":
                    return "<";
                case "&gt;":
                    return ">"
                case "&amp;":
                    return "&";
                case "&quot;":
                    return "\""
                case "\n":
                    return "<br/>"
            }
        })
    }

    // 显示最大的数字

    static showMaxCount(num, maxCount = 99) {
        num = num || 0
        num = num > maxCount ? maxCount : num
        return num
    }

    // 设置标题栏的题目

    static setNavBarTitle(title) {
        wx.setNavigationBarTitle({
            title: title || '秀购'
        })
    }

    static getUrlQuery(params) { // 获取参数
        let urlStr = params
        let urlArr = [];
        for (var i = 0; i < urlStr.split("&").length; i++) {
            urlArr.push(urlStr.split("&")[i].split("=")[0] ? urlStr.split("&")[i].split("=")[0] : "");
            urlArr.push(urlStr.split("&")[i].split("=")[1] ? urlStr.split("&")[i].split("=")[1] : "onlyKey")
        }
        if (urlStr == "") {
            return;
        } else {
            let urlObj = {}
            for (var i = 0; i < urlArr.length; i += 2) {
                if (urlArr[i] != "") {
                    urlObj[urlArr[i]] = decodeURIComponent(urlArr[i + 1]);
                }
            }
            return urlObj
        }
    }

    static createURL(url, param) { // 拼接参数
        let urlLink = '';
        for (let i in param) {
            let link = '&' + i + "=" + param[i]
            urlLink += link
        }
        urlLink = url + "?" + urlLink.substr(1);
        return urlLink.replace(' ', '');
    }

    static linkTo(url) { // 拼接参数
        let link = decodeURIComponent(url)
        let tab = [
            '/pages/index/index',
            '/pages/live/live-list/live-list',
            // '/pages/discover/discover',
            // '/pages/download-app/download-app',
            // '/pages/shopping-cart/shopping-cart',
            '/pages/my/my'
        ]
        let arr = tab.filter((item)=> {
            return link.indexOf(item) != -1
        })
        if (arr.length > 0) {
            this.switchTab(url)
        } else if (url.indexOf('/pages/login-wx/login-wx') != -1) {
            this.switchTab(tab[0])
        } else {
            this.redirectTo(url)
        }
    }

    static tranNumber(count=0, point=0) {
        // let numStr = num.toString()
        // // 十万以内直接返回
        // if (numStr.length <= 3) {
        //     return numStr;
        // }
        // //w
        // else if (numStr.length >6) {
        //     let decimal = numStr.substring(numStr.length -6, numStr.length - 5 + point);
        //     return parseFloat(parseInt(num / 1000000) + '.' + decimal) + 'w+';
        // }
        // //k
        // else if (numStr.length > 3) {
        //     let decimal = numStr.substring(numStr.length - 3, numStr.length - 2 + point)
        //     console.log(decimal)
        //     return parseFloat(parseInt(num / 1000) + '.' + decimal) + 'k+';
        // }
        if (count < 10000) {
            return count;
        }
        if (count - 10000 >= 0) {
            return (count / 10000).toFixed(1) + 'w+';
        }
    }

    static getMathRandom(l = 20, m = 480) {
        const res = []
        while(l) {
            let r = Math.floor(Math.random() * m)
            if(!res.includes(r)) {
                res.push(r)
                l--
            }
        }
        return res
    }

    static trimStr(str){
        return str.replace(/(^\s*)|(\s*$)/g,"");
    }

    static formatMoneyString (num, needSymbol = true) {
        let temp = (num || 0) + '';
        if (temp.indexOf('.') === -1) {
            temp += '.00';
        }
        //截取
        if ((temp.indexOf('.') + 3) < temp.length) {
            temp = temp.substr(0, temp.indexOf('.') + 3);
        }
        //添加
        if ((temp.indexOf('.') + 2 === temp.length)) {
            temp += '0';
        }

        if (needSymbol && temp.indexOf('¥') === -1) {
            temp = '¥' + temp;
        }
        return temp;
    }

    static filterEmoji(inputStr) {
        var ranges = ['\ud83c[\udf00-\udfff]', '\ud83d[\udc00-\ude4f]', '\ud83d[\ude80-\udeff]'];
        var emojireg = inputStr;
        emojireg = emojireg.replace(new RegExp(ranges.join('|'), 'g'), '');
        return emojireg;
    }

    static getParamsFromScene(scene) {
        scene = decodeURIComponent(scene);
        let arrParam = scene.split("&");
        let arr = [];
        let options = {}
        for (let i in arrParam) {
            arr = arrParam[i].split("=");
            options[arr[0]] = arr[1]
        }
        return options
    }

    static move (from,to){
		this.splice(to, 0, this.splice(from, 1)[0])
    }
    
    static hasNextPage(currentPage, pageSize, totalPage, currentPageNum) {
        if (pageSize * (currentPage - 1) + currentPageNum < totalPage) {
            return true
        } else {
            return false
        }
    }

}

